package com.rengwuxian.coursecoroutines._3_scope_context

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.AbstractCoroutineContextElement
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.coroutineContext

/**
 * 自定义CoroutineContext
 * CoroutineContext、AbstractCoroutineContextElement、CoroutineContext.Key
 *
 * 能用现成的，尽量用现成的，如果不能满足，再考虑。
 * 1.首先是CoroutineContext的类型。继承AbstractCoroutineContextElement
 * 2.声明类和专属属性。
 * 3.创建这个CoroutineContext，就可以在coroutineContext中拿到这个值了。
 * scope.launch(customContext) {
 *     coroutineContext[Logger]?.log()
 * }
 *
 * 想自定义一种CoroutineContext（可以模仿CoroutineName），可以传入参数。
 */
fun main() = runBlocking<Unit> {
  val scope = CoroutineScope(EmptyCoroutineContext)
  val customContext = Logger()
  scope.launch(customContext) {
    coroutineContext[Logger]?.log()
  }
  delay(10000)
}

class Logger : AbstractCoroutineContextElement(Logger) {
  companion object Key : CoroutineContext.Key<Logger>

  suspend fun log() {
    println("Current coroutine: $coroutineContext")
  }
}